package meeting

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"oa-rest/common"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	log "github.com/sirupsen/logrus"
	"xorm.io/xorm"
)

func newMeetingHandler(c *gin.Context) {
	var req Meeting
	var res common.Response
	if err := c.ShouldBindJSON(&req); err != nil {
		res.Format(c, err.Error())
		return
	}

	err := req.saveMeeting(c)
	if err != nil {
		res.Format(c, err.Error())
		return
	}
	res.Format(c)
}

// 获取当前登录人相关的meeting列表
func meetingListHandler(c *gin.Context) {
	var res common.Response
	meetings, err := getMeetingList(c)
	if err != nil {
		res.Format(c, err.Error())
		return
	}
	res.Data = meetings
	res.Format(c)
}

// 获取当前登录人相关的待处理会议列表(status=1)
func pendingMeetingListHandler(c *gin.Context) {
	var res common.Response
	meetings, err := getPendingMeetingList(c)
	if err != nil {
		res.Format(c, err.Error())
		return
	}
	res.Data = meetings
	res.Format(c)
}

// GenerateMinutesRequest 生成会议纪要请求
type GenerateMinutesRequest struct {
	MeetingID int64  `json:"meeting_id" form:"meeting_id"`
	AudioURL  string `json:"audio_url" form:"audio_url"`
}

// GenerateMinutesResponse 生成会议纪要响应
type GenerateMinutesResponse struct {
	Success        bool    `json:"success"`
	MeetingMinutes string  `json:"meeting_minutes"`
	Transcript     string  `json:"transcript"`
	ProcessingTime float64 `json:"processing_time"`
	AudioDuration  float64 `json:"audio_duration"`
	FileInfo       struct {
		AudioURL string `json:"audio_url"`
	} `json:"file_info"`
	ProcessingMethod string `json:"processing_method"`
}

// GenerateMinutesHandler 生成会议纪要的处理函数
func GenerateMinutesHandler(c *gin.Context) {
	var req GenerateMinutesRequest
	var res common.Response

	// 绑定请求数据
	if err := c.ShouldBind(&req); err != nil {
		res.Format(c, "请求参数错误: "+err.Error())
		return
	}

	// 验证参数
	if req.AudioURL == "" {
		res.Format(c, "音频URL不能为空")
		return
	}
	if req.MeetingID == 0 {
		res.Format(c, "会议ID不能为空")
		return
	}

	// 调用外部服务生成会议纪要
	response, err := callMinutesService(req.AudioURL)
	if err != nil {
		res.Format(c, "生成会议纪要失败: "+err.Error())
		return
	}

	// 调试：打印外部服务返回的数据
	log.Warnf("外部服务返回数据: %+v", response)

	// 检查外部服务是否成功处理
	if !response.Success {
		res.Format(c, "外部服务处理失败，无法生成会议纪要")
		return
	}

	// 验证返回数据的完整性
	if response.MeetingMinutes == "" && response.Transcript == "" {
		res.Format(c, "外部服务返回数据为空，请检查音频文件或稍后重试")
		return
	}

	// 更新会议记录
	err = updateMeetingWithMinutes(common.DB, req.MeetingID, req.AudioURL, response)
	if err != nil {
		log.Warnf("更新会议记录失败: %v", err)
		res.Format(c, "保存会议纪要失败: "+err.Error())
		return
	}

	// 返回结果
	res.Data = response
	res.Format(c)
}

// callMinutesService 调用外部会议纪要生成服务
func callMinutesService(audioURL string) (*GenerateMinutesResponse, error) {
	// 创建独立的HTTP客户端，因为会议纪要服务使用不同的端口
	client := &http.Client{
		Timeout: 120 * time.Second, // 设置超时时间
	}

	// 构建请求体
	requestBody := map[string]string{
		"audio_url": audioURL,
	}
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return nil, fmt.Errorf("序列化请求数据失败: %v", err)
	}

	// 创建请求
	req, err := http.NewRequest("POST", "http://60.208.118.42:30050/transcribe-minutes-from-url", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")

	// 调试：记录请求信息
	log.Warnf("调用会议纪要生成服务 - URL: %s, 音频URL: %s", "http://60.208.118.42:30050/transcribe-minutes-from-url", audioURL)

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 调试：记录响应状态
	log.Warnf("外部服务响应状态: %d %s", resp.StatusCode, resp.Status)

	// 读取响应体
	responseBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应体失败: %v", err)
	}

	// 调试：记录原始响应
	log.Warnf("外部服务原始响应: %s", string(responseBody))

	// 解析响应
	var response GenerateMinutesResponse
	err = json.Unmarshal(responseBody, &response)
	if err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	// 调试：记录响应数据
	log.Warnf("会议纪要生成服务响应: 成功=%v, 处理时间=%fs, 音频时长=%fs",
		response.Success, response.ProcessingTime, response.AudioDuration)

	return &response, nil
}

// updateMeetingWithMinutes 更新会议记录的纪要信息
func updateMeetingWithMinutes(engine *xorm.Engine, meetingID int64, audioURL string, response *GenerateMinutesResponse) error {
	// 检查数据库连接是否为空
	if engine == nil {
		log.Warnf("数据库连接为空，跳过数据库更新 - meetingID: %d", meetingID)
		return nil
	}

	// 调试：打印传入的参数
	log.Warnf("更新会议记录参数 - meetingID: %d, audioURL: %s", meetingID, audioURL)
	log.Warnf("响应数据 - MeetingMinutes: %s, Transcript: %s, ProcessingTime: %f, AudioDuration: %f, ProcessingMethod: %s",
		response.MeetingMinutes, response.Transcript, response.ProcessingTime, response.AudioDuration, response.ProcessingMethod)

	// 创建会议对象用于更新
	meeting := &Meeting{
		Id:                     meetingID,
		AudioUrl:               audioURL,
		MeetingMinutes:         response.MeetingMinutes,
		AudioTranscript:        response.Transcript,
		AudioProcessingTime:    response.ProcessingTime,
		AudioDuration:          response.AudioDuration,
		AudioProcessingMethod:  response.ProcessingMethod,
		Status:                 2, // 将状态从1改为2（表示已生成会议纪要）
	}

	// 更新数据库
	_, err := engine.ID(meetingID).Cols(
		"audio_url",
		"meeting_minutes",
		"audio_transcript",
		"audio_processing_time",
		"audio_duration",
		"audio_processing_method",
		"status").Update(meeting)

	return err
}

// GetMeetingMinutesHandler 获取会议纪要的处理函数
func GetMeetingMinutesHandler(c *gin.Context) {
	var res common.Response

	// 获取会议ID参数
	meetingIDStr := c.Query("meeting_id")
	if meetingIDStr == "" {
		res.Format(c, "会议ID不能为空")
		return
	}

	meetingID, err := strconv.ParseInt(meetingIDStr, 10, 64)
	if err != nil {
		res.Format(c, "会议ID格式错误")
		return
	}

	// 查询会议记录
	var meeting Meeting
	has, err := common.DB.ID(meetingID).Get(&meeting)
	if err != nil {
		res.Format(c, "查询会议记录失败: "+err.Error())
		return
	}

	if !has {
		res.Format(c, "会议不存在")
		return
	}

	// 返回会议纪要相关信息
	if meeting.MeetingMinutes == "" {
		res.Format(c, "该会议暂无纪要")
		return
	}

	// 构建响应数据
	response := map[string]interface{}{
		"meeting_id":            meeting.Id,
		"audio_url":             meeting.AudioUrl,
		"meeting_minutes":       meeting.MeetingMinutes,
		"audio_transcript":      meeting.AudioTranscript,
		"audio_processing_time": meeting.AudioProcessingTime,
		"audio_duration":        meeting.AudioDuration,
		"processing_method":    meeting.AudioProcessingMethod,
	}

	res.Data = response
	res.Format(c)
}

func RegisterRoutes(group *gin.RouterGroup) {
	group.POST("/meeting/newMeeting", newMeetingHandler)
	group.GET("/meeting/list", meetingListHandler)
	group.GET("/meeting/pending", pendingMeetingListHandler)
	// 注册会议纪要相关路由
	group.POST("/meeting/minutes/generate", GenerateMinutesHandler)
	group.GET("/meeting/minutes/get", GetMeetingMinutesHandler)
}
